package com.googlecode.gwtCorsForIe8.server;

import java.io.IOException;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CorsFilter implements Filter {

	private static final String USER_AGENT = "user-agent";
	private static final String ORIGIN_HEADER = "Origin";
	private static final String ACCESS_CONTROL_ALLOW_ORIGIN_HEADER = "Access-Control-Allow-Origin";
	private static final String ACCESS_CONTROL_ALLOW_METHODS_HEADER = "Access-Control-Allow-Methods";
	private static final String ACCESS_CONTROL_ALLOW_HEADERS_HEADER = "Access-Control-Allow-Headers";
	private String contextPath;

	@Override
	public void destroy() {

	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest req = (HttpServletRequest) request;
		HttpServletResponse resp = (HttpServletResponse) response;
		String origin = req.getHeader(ORIGIN_HEADER);
		String ua = req.getHeader(USER_AGENT);
		if (origin != null) {

			if ("OPTIONS".equals(req.getMethod())) {

				resp.setHeader(ACCESS_CONTROL_ALLOW_ORIGIN_HEADER, origin);
				// if (allowCredentials)
				// response.setHeader(ACCESS_CONTROL_ALLOW_CREDENTIALS_HEADER,
				// "true");
				// 5.2.8
				// if (preflightMaxAge > 0)
				// response.setHeader(ACCESS_CONTROL_MAX_AGE_HEADER,
				// String.valueOf(preflightMaxAge));
				// 5.2.9

				String allowedMethodsConfig = "POST";
				List<String> allowedMethods = new LinkedList<String>();
				allowedMethods.addAll(Arrays.asList(allowedMethodsConfig
						.split(",")));

				String allowedHeadersConfig = "X-Requested-With,Content-Type,Accept,x-gwt-module-base,x-gwt-permutation";
				List<String> allowedHeaders = new LinkedList<String>();
				allowedHeaders.addAll(Arrays.asList(allowedHeadersConfig
						.split(",")));

				resp.setHeader(ACCESS_CONTROL_ALLOW_METHODS_HEADER,
						commify(allowedMethods));
				// 5.2.10
				resp.setHeader(ACCESS_CONTROL_ALLOW_HEADERS_HEADER,
						commify(allowedHeaders));
				// super.doOptions(req, resp);

			} else if ("POST".equals(req.getMethod())) {
				if (ua.equals("ie8")) {
					System.out.println("ie8");
				}

				request = new GWTRequest(req, contextPath);
				resp.setHeader(ACCESS_CONTROL_ALLOW_ORIGIN_HEADER, origin);
			}
		}

		chain.doFilter(request, response);
	}

	private String commify(List<String> strings) {
		StringBuilder builder = new StringBuilder();
		for (int i = 0; i < strings.size(); ++i) {
			if (i > 0)
				builder.append(',');
			String string = strings.get(i);
			builder.append(string);
		}
		return builder.toString();
	}

	@Override
	public void init(FilterConfig conf) throws ServletException {
		contextPath = conf.getInitParameter("contextPath");
	}

}
